﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Vds2465Telegrams;

namespace Vds2465Parser
{
	internal static class FixedLength
	{
		#region constants

        private const int fixedLengthTelegrams_Length = 5;
        private const byte fixedLengthTelegrams_FirstByteValue = 0x10;
        private const byte fixedLengthTelegrams_LastByteValue = 0x16;

		private const byte positionOfControlField = 1;
		private const byte positionOfAddressByte = 2;
		private const byte positionOfCheckSum = 3;

		#endregion constants

		internal static byte[] Generate_FixedLengthTelegram(byte controlField, byte addressField)
		{
			byte[] telegramBytes = new byte[fixedLengthTelegrams_Length];
			telegramBytes[0] = fixedLengthTelegrams_FirstByteValue;  // Start

			telegramBytes[positionOfControlField] = controlField;

			telegramBytes[positionOfAddressByte] = addressField;

			telegramBytes[positionOfCheckSum] = (byte)((byte)telegramBytes[1] + (byte)telegramBytes[2]);

			telegramBytes[4] = fixedLengthTelegrams_LastByteValue;  // Ende

			return telegramBytes;
		}

        internal static bool IsThisAFixedLengthTelegram(byte[] telegramBytes)
        {
            return telegramBytes[0] == FixedLength.fixedLengthTelegrams_FirstByteValue;
        }

        internal static Telegram Parse_FixedLengthTelegram(byte[] fixedLengthTelegramBytes)
        {
            if (fixedLengthTelegramBytes.Length == fixedLengthTelegrams_Length)
            {
				byte address = fixedLengthTelegramBytes[positionOfAddressByte];

                bool calling;
				ControlField.IsThisCallingOrReturning(fixedLengthTelegramBytes[positionOfControlField], out calling);
                if (calling)
                {
                    eDirection direction;
                    bool frameCountValid;
                    bool frameCountFlag;
                    eTelegramFunction_Calling telegramFunction;
					bool bRetVal = ControlField.Parse_ControlField_Calling(fixedLengthTelegramBytes[positionOfControlField], out direction, out frameCountValid, out frameCountFlag, out telegramFunction);
                    if (bRetVal)
                    {
						Telegram_Calling telegramCalling = new Telegram_Calling(direction, address, telegramFunction, frameCountValid, frameCountFlag);
                        return telegramCalling;
                    }

					// TODO handle error
                    return null;
                }
                else
                {
                    eDirection direction;
                    bool accessDemandFlag;
                    bool dataFlowControlStopFlag;
                    eTelegramFunction_Returning telegramFunction;
					bool bRetVal = ControlField.Parse_ControlField_Returning(fixedLengthTelegramBytes[positionOfControlField], out direction, out accessDemandFlag, out dataFlowControlStopFlag, out telegramFunction);
                    if (bRetVal)
                    {
						Telegram_Returning telegramReturning = new Telegram_Returning(direction, address, telegramFunction, accessDemandFlag, dataFlowControlStopFlag);
                        return telegramReturning;
                    }

					// TODO handle error
                    return null;
                }
            }
            else
            {
				// TODO handle error
                return null;
            }
        }
	}
}
